package com.caocaog.market.utils;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.caocaog.market.entity.ShopPrinter;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.HttpClientUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 芯烨云打印机工具类
 *
 * @author chechen
 * @date 2021-01-14
 * @see <a href="https://www.xpyun.net/open/index.html">芯烨云开放平台</a>
 */
public class XyyPrinterUtil {

    private XyyPrinterUtil() {}

    /** 芯烨云平台注册用户名（开发者 ID） */
    private static final String USER = "junyihe_100@163.com";
    /** 开发者密钥 */
    private static final String USER_KEY = "e0b03d3a949645f4a67b9b9304cf3d4b";

    private static final String ERROR_MESSAGE = "芯烨云开放平台 api 无返回结果";

    /** 添加打印机到开发者账户（可批量）URL */
    private static final String ADD_URL = "https://open.xpyun.net/api/openapi/xprinter/addPrinters";
    /** 批量删除打印机 URL */
    private static final String DELETE_URL = "https://open.xpyun.net/api/openapi/xprinter/delPrinters";
    /** 修改打印机信息 URL */
    private static final String UPDATE_URL = "https://open.xpyun.net/api/openapi/xprinter/updPrinter";
    /** 获取指定打印机状态 URL */
    private static final String PRINTER_STATUS_URL = "https://open.xpyun.net/api/openapi/xprinter/queryPrinterStatus";
    /** 打印小票订单 */
    private static final String TEXT_PRINT_URL = "https://open.xpyun.net/api/openapi/xprinter/print";


    /**
     * 打印信息
     *
     * @param orderInfo   要打印的订单信息
     * @param machineCode 打印机打印机号
     * @param cascadeCount 打印次数
     */
    public static String print(String orderInfo, String machineCode, int cascadeCount) {
        Map<String, Object> params = getParams();
        params.put("sn", machineCode);
        params.put("content", orderInfo);
        params.put("copies", String.valueOf(cascadeCount));

        String jsonRequest = JSON.toJSONString(params);
        String resp = HttpClientUtil.doPostJSON(TEXT_PRINT_URL, jsonRequest);
        return unifiedProcessingResult(resp);
    }

    /**
     * 添加打印机
     *
     * @param shopPrinter 打印机信息
     * @return 是否成功
     */
    public static String addPrinter(ShopPrinter shopPrinter) {
        Map<String, Object> params = getParams();
        params.put("items", Collections.singletonList(new HashMap<String, Object>() {{
            put("name", shopPrinter.getName());
            put("sn", shopPrinter.getNumber());
        }}));

        String jsonRequest = JSON.toJSONString(params);
        System.out.println(jsonRequest);
        String resp = HttpClientUtil.doPostJSON(ADD_URL, jsonRequest);
        return unifiedProcessingResult(resp);
    }

    /**
     * 修改打印机授权
     *
     * @param shopPrinter 打印机信息
     * @return 是否成功
     */
    public static String updatePrinter(ShopPrinter shopPrinter) {
        Map<String, Object> params = getParams();
        params.put("sn", shopPrinter.getNumber());
        params.put("name", shopPrinter.getName());
        params.put("cardno", shopPrinter.getSimNumber());

        String jsonRequest = JSON.toJSONString(params);
        System.out.println(jsonRequest);
        String resp = HttpClientUtil.doPostJSON(UPDATE_URL, jsonRequest);
        return unifiedProcessingResult(resp);
    }

    /**
     * 删除打印机授权
     *
     * @param machineCode 易联云打印机打印机号
     * @return 是否成功
     */
    public static String deletePrinter(String machineCode) {
        Map<String, Object> params = getParams();
        params.put("snlist", Collections.singletonList(machineCode));

        String jsonRequest = JSON.toJSONString(params);
        System.out.println(jsonRequest);
        String resp = HttpClientUtil.doPostJSON(DELETE_URL, jsonRequest);
        return unifiedProcessingResult(resp);
    }

    /**
     * 获取打印机状态
     *
     * @param sn 打印机编号
     * @return 打印机状态
     */
    public static Result<String> getStatus(String sn) {
        Map<String, Object> params = getParams();
        params.put("sn", sn);

        String jsonRequest = JSON.toJSONString(params);
        System.out.println(jsonRequest);
        String resp = HttpClientUtil.doPostJSON(PRINTER_STATUS_URL, jsonRequest);
        if (StringUtils.isBlank(resp)) {
            return Result.error(null, ERROR_MESSAGE);
        }
        JSONObject resultJsonObject = JSON.parseObject(resp);
        if (!resultJsonObject.containsKey("data")) {
            return Result.error(null, "未知");
        }
        int data = resultJsonObject.getInteger("data");
        if (data == 0) {
            return Result.OK("离线");
        } else if (data == 1) {
            return Result.OK("在线-正常");
        } else if (data == 2) {
            return Result.OK("在线-异常");
        } else {
            return Result.error(null, resultJsonObject.getString("msg"));
        }
    }

    /**
     * 生成签名字符串
     * @param timestamp 时间戳
     * @return 签名字符串
     */
    private static String signature(String timestamp) {
        return SecureUtil.sha1(USER + USER_KEY + timestamp);
    }

    /**
     * 返回通用的请求参数
     *
     * @return 请求参数
     */
    private static Map<String, Object> getParams() {
        // 获取北京时间（UTC+08:00）秒数
        final String TIMESTAMP = String.valueOf(LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
        return new HashMap<String, Object>() {{
            put("user", USER);
            put("timestamp", TIMESTAMP);
            put("sign", signature(TIMESTAMP));
        }};
    }

    private static String unifiedProcessingResult(String resp) {
        JSONObject jsonObject = JSON.parseObject(resp);
        System.out.println(jsonObject);
        return null;
    }

    /**
     * 统一处理返回结果
     * 请求成功返回null，请求失败返回错误信息
     *
     * @param post 返回结果
     * @return 错误信息/null
     */
    private static String unifiedProcessingResult(PostMethod post) {
        InputStream inputStream;
        StringBuffer stringBuffer = new StringBuffer();
        try {
            inputStream = post.getResponseBodyAsStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String str;
            while ((str = bufferedReader.readLine()) != null) {
                stringBuffer.append(str);
            }
            if (StringUtils.isBlank(stringBuffer.toString())) {
                return ERROR_MESSAGE;
            }
            System.out.println(stringBuffer);
            JSONObject resultJsonObject = JSONObject.parseObject(stringBuffer.toString());
            if ("0".equals(resultJsonObject.getString("data"))) {
                return null;
            }
            return resultJsonObject.getString("msg");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ERROR_MESSAGE;
    }

}
